//
//  DTKMapBundleBundle.m
//  DTKMapBundleBundle
//
//  Created by ddev CLI Tools on 2021/3/24.
//

#import "DTKMapBundle.h"
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <MAMapKit/MAMapKit.h>
#import "SearchMapViewController.h"
#import "PreviewViewController.h"
#import <AMapLocationKit/AMapLocationKit.h>
#import "Location.h"
#import <AMapSearchKit/AMapSearchKit.h>
#import <DGOpenAPI/DGOpenAPI.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import "OpenMapParam.h"
#import "LocationUtil.h"
#import <CoreLocation/CoreLocation.h>
#define DTKMapBundle_BundleId @"dn9zdb3v"
DTKExternalBundleRegister(DTKMapBundle)

@interface DTKMapBundle ()<AMapLocationManagerDelegate, AMapSearchDelegate, AMapGeoFenceManagerDelegate>

@property(nonatomic, strong) AMapLocationManager *locationManager;
@property(nonatomic, copy) void (^completeBlock)(id<DGLBSLocation> _Nullable location, NSError * _Nullable error);
@property(nonatomic, strong)NSTimer *timer;
@property(nonatomic,strong)NSDate *nextCheckBeginDate;
@property(nonatomic,strong)NSDate *nextCheckEndDate;
@property(nonatomic, assign)NSInteger canQuickFailCount;
@end

@implementation DTKMapBundle

#pragma mark - BundleId

- (NSString *)bundleId {
    return DTKMapBundle_BundleId;
}

#pragma mark - Bundle life cycle

- (void)bundleDidLoaded {
    DTKELog([DTKMapBundle logger], @"DTKMapBundle did loaded");
//    [AMapServices sharedServices].apiKey = @"8619714f314ea5aaff6af762680a40ee";//test  //@"b44565170ad56899fc8a662b60f93012";prod
    [AMapServices sharedServices].apiKey = @"b44565170ad56899fc8a662b60f93012";
    self.locationManager = [[AMapLocationManager alloc] init];
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    self.locationManager.pausesLocationUpdatesAutomatically = YES;
    self.locationManager.delegate = self;
    self.canQuickFailCount = 0;
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusDenied) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"你已禁止授予钉钉定位权限，可能会造成功能不可用，如需使用请到设置里授予权限" message:nil preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        [alert addAction:cancelAction];
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"前往设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL finished){
                
            }];
        }];
        [alert addAction:confirmAction];
        [[DTKMapBundle uiHierachyService].currentTopViewController presentViewController:alert animated:YES completion:nil];
    }
}

#pragma mark - Bundle services

+ (DTKExternalServiceInvoker *)services {
    static dispatch_once_t onceToken;
    static DTKExternalServiceInvoker *DTKMapBundleServiceInvoker;
    dispatch_once(&onceToken, ^{
        DTKMapBundleServiceInvoker = [[DTKExternalServiceInvoker alloc] initWithBundleId:DTKMapBundle_BundleId];
    });
    return DTKMapBundleServiceInvoker;
}

+ (id<DTKExternalLogServiceProtocol>)logger {
    return [[self services] logger];
}

+ (id<DTKExternalOpenServiceInvokeProtocol>)openServices {
    return [[self services] openServiceInvoker];
}

+ (id<DTKExternalUIHierarchyServiceProtocol>)uiHierachyService {
    return [[self services] uiHierachyService];
}

- (void)onUserDidLogout {
    
}

- (void)onUserDidLogin:(DTKExternalUserId)userId {
    if (!self.timer) {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(checkRepeatly) userInfo:nil repeats:YES];
    }
}

-(void)checkRepeatly {
    UIApplicationState state = [[UIApplication sharedApplication]applicationState];
    if (state == UIApplicationStateActive) {
        [self checkIfCanQuick:^(id  _Nullable response, NSError * _Nullable error) {
            BOOL status = [[response valueForKey:@"status"]boolValue];
            if (status) {
                NSArray *placeList = response[@"placeList"];
                NSArray *wifiList = response[@"wifiList"];
                NSLog(@"打卡地点列表是:%@",placeList);
                NSLog(@"WIFI列表是:%@",wifiList);
                [self.locationManager requestLocationWithReGeocode:NO completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
                    if (location) {
                        NSLog(@"当前定位是:%@",location);
                        BOOL inArea = NO;
                        for (NSDictionary *place in placeList) {
                            CLLocationDegrees latitude = [place[@"latitude"] doubleValue];
                            CLLocationDegrees longitude = [place[@"longitude"] doubleValue];
                            double inDistance = [place[@"scope"] floatValue];
                            CLLocation *placeLocation = [[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
                            double distance = [placeLocation distanceFromLocation:location];
                            if (distance < inDistance) {
                                inArea = YES;
                                break;
                            }
                        }
                        NSLog(@"是否在打卡区域:%i",inArea);
                        [self getConnectedWifiInfo:^(NSArray *list) {
                            BOOL connectTargetWifi = NO;
                            if ([list count] > 0) {
                                NSDictionary *wifi = [list firstObject];
                                NSString *mac = wifi[@"mac"];
                                for (NSString *checkWifi in wifiList) {
                                    NSString *checkmac = checkWifi;
                                    if ([mac isEqualToString:checkmac]) {
                                        connectTargetWifi = YES;
                                        break;
                                    }
                                }
                            }
                            NSLog(@"获取到的WIFI列表是:%@",list);
                            NSLog(@"是否可打卡:%i",inArea || connectTargetWifi);
                            if (inArea || connectTargetWifi) {
                                [self doCheck:location code:regeocode wifiInfo:[list firstObject]];
                            }
                        }];
                    }
                    else {
                        NSLog(@"定位发生错误:%@",error);
                    }
                }];
            }
        }];
    }
}

//判断是否可以极速打卡
-(void)checkIfCanQuick:(void (^ _Nonnull)(id _Nullable response, NSError * _Nullable error))completionHandler {
    id<DGStartRequestOpenServiceProtocol> requestService = [[DTKMapBundle openServices]openServiceForProtocol:@protocol(DGStartRequestOpenServiceProtocol)];
    NSMutableDictionary *param = [NSMutableDictionary dictionary];
    param[@"method"] = @"POST";
    [requestService startRequest:@"/external/kaoqin/prod/clock/app/canQuick" parameters:param completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        NSLog(@"是否可以极速打卡接口返回是:%@",response);
        if ([response isKindOfClass:[NSDictionary class]]) {
            if (completionHandler) {
                completionHandler(response, error);
            }
        } else {
            //出错了
            self.canQuickFailCount += 1;
            if (self.canQuickFailCount > 30) {
                [self.timer invalidate];
                self.timer = nil;
                self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(checkRepeatly) userInfo:nil repeats:YES];
                self.canQuickFailCount = 0;
            } else {
                if (self.timer.timeInterval < 10) {
                    [self.timer invalidate];
                    self.timer = nil;
                    self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(checkRepeatly) userInfo:nil repeats:YES];
                }
            }
        }
    }];
}

//执行打卡接口
-(void)doCheck:(CLLocation *)location code:(AMapLocationReGeocode *)code wifiInfo:(NSDictionary *)wifiInfo {
    id<DGStartRequestOpenServiceProtocol> requestService = [[DTKMapBundle openServices]openServiceForProtocol:@protocol(DGStartRequestOpenServiceProtocol)];
    NSMutableDictionary *param = [NSMutableDictionary dictionary];
    param[@"method"] = @"POST";
    if (wifiInfo) {
        NSString *mac = wifiInfo[@"mac"];
        param[@"wifiMac"] = mac;
    }
    param[@"longitude"] = [NSString stringWithFormat:@"%f",location.coordinate.longitude];
    param[@"latitude"] = [NSString stringWithFormat:@"%f",location.coordinate.latitude];
    if (code) {
        param[@"addressDetail"] = code.formattedAddress;
    } else {
        param[@"addressDetail"] = @"";
    }
    param[@"deviceType"] = @"mobile";
    NSString *deviceID = [SSKeychain passwordForService:@"TBDeviceID" account:@"TBDeviceID"];
    if (deviceID == nil) {
        deviceID = [[[UIDevice currentDevice]identifierForVendor]UUIDString];
        [SSKeychain setPassword:deviceID forService:@"TBDeviceID" account:@"TBDeviceID"];
    }
    param[@"deviceNo"] = deviceID;
    NSLog(@"极速打卡请求数据是:%@",param);
    [requestService startRequest:@"/external/kaoqin/prod/clock/app/quickClock" parameters:param completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        NSLog(@"极速打卡接口返回是:%@",response);
        if (response) {
            BOOL is_finish = [response[@"is_finish"] boolValue];
            if (is_finish) {
                //如果打卡成功
                if (self.timer) {
                    [self.timer invalidate];
                    self.timer = nil;
                }
                NSArray *next_time = response[@"next_time"];
                NSTimeInterval beginTime = [[next_time firstObject]doubleValue];
                self.timer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(checkRepeatly) userInfo:nil repeats:YES];
                NSDate *date = [NSDate dateWithTimeIntervalSince1970:beginTime / 1000];
                [[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
                [self.timer setFireDate:date];
                NSLog(@"下一个轮询日期是:%@",date);
            }
        }
    }];
}

-(void)getConnectedWifiInfo:(void (^ _Nonnull)(id _Nullable response))callback {
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    NSLog(@"supported interfaces is %@", ifs);
    NSMutableArray *wifiList = [NSMutableArray array];
    for (NSString *ifnam in ifs) {
        NSMutableDictionary *param = [NSMutableDictionary dictionary];
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        NSLog(@"network info is %@", info);
        if ([info isKindOfClass:[NSDictionary class]]) {
            if (info[@"SSID"]) {
                param[@"isConnect"] = @(YES);
                param[@"ssid"] = info[@"SSID"];
            }
            if (info[@"BSSID"]) {
                param[@"mac"] = info[@"BSSID"];
            }
        }
        NSLog(@"param is %@", param);
        [wifiList addObject:param];
        break;
    }
    if (callback) {
        callback(wifiList);
    }
}

# pragma mark - DGEMapPluginProtocol

// 选取地图位置
- (void)openLocationPicker:(id <DGEMapPickerParam>)pickerParam completion:(DGELBSLocationCompletion)completion{
    
    SearchMapViewController* shareVC = [[SearchMapViewController alloc] initWithBlock: completion];
    shareVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [[DTKMapBundle uiHierachyService].currentTopViewController presentViewController:shareVC animated:YES completion:nil];
}

// 预览地图
- (void)openLocationPreviewPage:(id <DGEMapPreviewParam>)previewParam{
    
    PreviewViewController* shareVC = [[PreviewViewController alloc] initWithInfo:previewParam];
    shareVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [[DTKMapBundle uiHierachyService].currentTopViewController presentViewController:shareVC animated:YES completion:nil];
}

// 创建预览地图的视图控制器
- (__kindof UIViewController * _Nullable)createLocationPreviewController:(id <DGEMapPreviewParam>)previewParam{
    
    PreviewViewController* shareVC = [[PreviewViewController alloc] initWithInfo:previewParam];
    return shareVC;
}

#pragma mark - DGELocationPluginProtocol

// 逆地理位置解析
- (void)regeoSearchWithLocation:(nonnull CLLocation *)location completion:(nonnull DGELocationRegeoSearchCompletion)completion {
    AMapSearchAPI *search = [[AMapSearchAPI alloc] init];
    search.delegate = self;
    AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
    regeo.location = [AMapGeoPoint locationWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
    regeo.requireExtension = YES;
    [search AMapReGoecodeSearch:regeo];
    self.completeBlock = completion;
}

// 请求单次定位
- (void)requestLocationWithCompletion:(nonnull DGELocationUpdatingLocationCompletion)completion {
    
    [self.locationManager requestLocationWithReGeocode: YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        if (regeocode) {
            
            Location *loc = [[Location alloc] init];
            loc.country = regeocode.country;
            loc.province = regeocode.province;
            loc.city = regeocode.city;
            loc.district = regeocode.district;
            loc.street = regeocode.street;
            loc.location = [[CLLocation alloc] initWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
            completion(loc, error);
        }
    }];
}

//地理围栏回调
- (void)amapGeoFenceManager:(AMapGeoFenceManager *)manager didGeoFencesStatusChangedForRegion:(AMapGeoFenceRegion *)region customID:(NSString *)customID error:(NSError *)error {
//    if (!error) {
//        //已经进入了该区域
//        AMapGeoFenceRegionStatus status = [region fenceStatus];
//        if (status == AMapGeoFenceRegionStatusInside) {
//            //已进入区域
//            [self timerlyCheck];
//        } else if (status == AMapGeoFenceRegionStatusOutside){
//            //已离开区域
//        }
//    }
}


// 开始连续定位
- (void)startUpdatingLocation {
    
    [self.locationManager startUpdatingLocation];
}

// 停止连续定位
- (void)stopUpdatingLocation {
    
    [self.locationManager stopUpdatingLocation];
}

#pragma  mark - DGELocationPluginDelegate

- (void)dge_locationManager:(id<DGELocationPluginProtocol>)manager didUpdateLocation:(CLLocation *)location{
    
}

- (void)dge_locationManager:(nonnull id<DGELocationPluginProtocol>)manager didFailWithError:(nonnull NSError *)error {
    
}


#pragma mark - AMapLocationManagerDelegate

- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{
    
}

#pragma mark - AMapSearchDelegate

/* 逆地理编码回调. */
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response{
    if (response.regeocode != nil) {
        Location *loc = [[Location alloc] init];
        loc.address = response.regeocode.formattedAddress;
        loc.country = response.regeocode.addressComponent.country;
        loc.province = response.regeocode.addressComponent.province;
        loc.city = response.regeocode.addressComponent.city;
        loc.district = response.regeocode.addressComponent.district;
        loc.street = response.regeocode.addressComponent.township;
        loc.location = [[CLLocation alloc] initWithLatitude:request.location.latitude longitude:request.location.longitude];
        self.completeBlock(loc, nil);
    }
}

@synthesize allowsBackgroundLocationUpdates;

@synthesize locationTimeout;

@synthesize reGeocodeTimeout;

@synthesize delegate;

@synthesize needReGeocode;

@synthesize desiredAccuracy;

@end
